﻿using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using ICE.POS.Common;
using System.Media;
using ICE.Utility;

namespace ICE.POS
{
    /// <summary>
    /// 语音播报辅助类
    /// </summary>
    public class VoiceNotificationHelper
    {
        private static readonly string ApiUrl = "https://dds.dui.ai/runtime/v1/synthesize"; // TTS API URL
        private static readonly string DefaultVoiceId = "xiyaof_qingxin"; // 默认音色：小妖(清新甜美)
        private static readonly float DefaultSpeed = 1.0f; // 默认语速
        private static readonly int DefaultVolume = 80; // 默认音量
        private static readonly float DefaultVolumeGain = 1.0f; // 默认音量增益（1.0表示不增益）
        private static readonly string DefaultAudioType = "wav"; // 默认音频类型
        
        // 单例模式
        private static VoiceNotificationHelper _instance;
        private static readonly object _lock = new object();

        public static VoiceNotificationHelper Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_lock)
                    {
                        if (_instance == null)
                        {
                            _instance = new VoiceNotificationHelper();
                        }
                    }
                }
                return _instance;
            }
        }

        // 语音类型：local-本地音频文件，api-在线TTS服务
        private string _ttsType = "api";
        // 音色ID
        private string _voiceId = DefaultVoiceId;
        // 语速
        private float _speed = DefaultSpeed;
        // 音量
        private int _volume = DefaultVolume;
        // 音量增益
        private float _volumeGain = DefaultVolumeGain;
        // 音频类型
        private string _audioType = DefaultAudioType;
        // 本地音频文件目录
        private string _localAudioDir = "";

        // 属性访问器
        public string TtsType
        {
            get { return _ttsType; }
            set { _ttsType = value; }
        }

        public string VoiceId
        {
            get { return _voiceId; }
            set { _voiceId = value; }
        }

        public float Speed
        {
            get { return _speed; }
            set { _speed = value; }
        }

        public int Volume
        {
            get { return _volume; }
            set { _volume = value; }
        }

        public float VolumeGain
        {
            get { return _volumeGain; }
            set { _volumeGain = value; }
        }

        private VoiceNotificationHelper()
        {
            // 从配置文件加载设置
            LoadSettings();
        }

        /// <summary>
        /// 从配置文件加载设置
        /// </summary>
        private void LoadSettings()
        {
            try
            {
                string configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config", "tts_settings.ini");
                
                // 检查tts目录是否存在，如果存在则优先使用
                string ttsDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tts");
                if (Directory.Exists(ttsDir))
                {
                    _localAudioDir = ttsDir;
                    LoggerHelper.Log("MsmkLogger", "检测到tts目录，将使用该目录作为本地音频目录: " + ttsDir, LogEnum.SysLog);
                }
                else
                {
                    _localAudioDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Audio");
                    LoggerHelper.Log("MsmkLogger", "未检测到tts目录，将使用默认Audio目录: " + _localAudioDir, LogEnum.SysLog);
                }
                
                if (File.Exists(configPath))
                {
                    string[] lines = File.ReadAllLines(configPath);
                    foreach (string line in lines)
                    {
                        if (string.IsNullOrEmpty(line) || line.StartsWith("#"))
                            continue;

                        string[] parts = line.Split('=');
                        if (parts.Length != 2)
                            continue;

                        string key = parts[0].Trim();
                        string value = parts[1].Trim();

                        switch (key.ToLower())
                        {
                            case "ttstype":
                                _ttsType = value;
                                break;
                            case "voiceid":
                                _voiceId = value;
                                break;
                            case "speed":
                                float.TryParse(value, out _speed);
                                break;
                            case "volume":
                                int.TryParse(value, out _volume);
                                break;
                            case "volumegain":
                                float.TryParse(value, out _volumeGain);
                                break;
                            case "audiotype":
                                _audioType = value;
                                break;
                            case "localaudiodir":
                                // 如果配置文件中指定了目录，且该目录存在，则使用该目录
                                string configDir = value;
                                if (!string.IsNullOrEmpty(configDir))
                                {
                                    if (!Path.IsPathRooted(configDir))
                                    {
                                        configDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, configDir);
                                    }
                                    
                                    if (Directory.Exists(configDir))
                                    {
                                        _localAudioDir = configDir;
                                        LoggerHelper.Log("MsmkLogger", "从配置文件加载本地音频目录: " + _localAudioDir, LogEnum.SysLog);
                                    }
                                }
                                break;
                        }
                    }
                }
                else
                {
                    // 创建默认配置文件
                    Directory.CreateDirectory(Path.GetDirectoryName(configPath));
                    using (StreamWriter sw = new StreamWriter(configPath))
                    {
                        sw.WriteLine("# TTS设置");
                        sw.WriteLine("TtsType=api");
                        sw.WriteLine("VoiceId=" + DefaultVoiceId);
                        sw.WriteLine("Speed=" + DefaultSpeed);
                        sw.WriteLine("Volume=" + DefaultVolume);
                        sw.WriteLine("VolumeGain=" + DefaultVolumeGain);
                        sw.WriteLine("AudioType=" + DefaultAudioType);
                        sw.WriteLine("LocalAudioDir=tts");  // 默认使用tts目录
                    }
                }

                // 确保本地音频目录存在
                if (!Directory.Exists(_localAudioDir))
                {
                    Directory.CreateDirectory(_localAudioDir);
                    LoggerHelper.Log("MsmkLogger", "创建本地音频目录: " + _localAudioDir, LogEnum.SysLog);
                }
                
                LoggerHelper.Log("MsmkLogger", "TTS设置加载完成: TtsType=" + _ttsType + ", VoiceId=" + _voiceId + 
                    ", 本地音频目录=" + _localAudioDir, LogEnum.SysLog);
            }
            catch (Exception ex)
            {
                LoggerHelper.Log("MsmkLogger", "加载TTS设置失败: " + ex.Message, LogEnum.SysLog);
            }
        }

        /// <summary>
        /// 保存设置到配置文件
        /// </summary>
        public void SaveSettings()
        {
            try
            {
                string configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config", "tts_settings.ini");
                Directory.CreateDirectory(Path.GetDirectoryName(configPath));
                using (StreamWriter sw = new StreamWriter(configPath))
                {
                    sw.WriteLine("# TTS设置");
                    sw.WriteLine("TtsType=" + _ttsType);
                    sw.WriteLine("VoiceId=" + _voiceId);
                    sw.WriteLine("Speed=" + _speed);
                    sw.WriteLine("Volume=" + _volume);
                    sw.WriteLine("VolumeGain=" + _volumeGain);
                    sw.WriteLine("AudioType=" + _audioType);
                    sw.WriteLine("LocalAudioDir=" + _localAudioDir);
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.Log("MsmkLogger", "保存TTS设置失败: " + ex.Message, LogEnum.SysLog);
            }
        }

        /// <summary>
        /// 设置TTS类型
        /// </summary>
        /// <param name="ttsType">TTS类型：local-本地音频文件，api-在线TTS服务</param>
        public void SetTtsType(string ttsType)
        {
            _ttsType = ttsType;
        }

        /// <summary>
        /// 设置音色ID
        /// </summary>
        /// <param name="voiceId">音色ID</param>
        public void SetVoiceId(string voiceId)
        {
            _voiceId = voiceId;
        }

        /// <summary>
        /// 设置语速
        /// </summary>
        /// <param name="speed">语速</param>
        public void SetSpeed(float speed)
        {
            _speed = speed;
        }

        /// <summary>
        /// 设置音量
        /// </summary>
        /// <param name="volume">音量</param>
        public void SetVolume(int volume)
        {
            _volume = volume;
        }

        /// <summary>
        /// 设置音量增益
        /// </summary>
        /// <param name="volumeGain">音量增益</param>
        public void SetVolumeGain(float volumeGain)
        {
            _volumeGain = volumeGain;
        }

        /// <summary>
        /// 使用TTS API播放语音
        /// </summary>
        /// <param name="text">要播放的文本</param>
        /// <returns>是否成功播放</returns>
        public bool PlayTtsApi(string text)
        {
            try
            {
                LoggerHelper.Log("MsmkLogger", "开始TTS播放: " + text, LogEnum.SysLog);
                
                // 确保TLS 1.2
                System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)3072;
                
                // 创建临时文件路径
                string tempFilePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + "." + _audioType);

                // 构建API请求URL，添加音量增益参数
                string apiUrl = string.Format("{0}?voiceId={1}&text={2}&speed={3}&volume={4}&volumeGain={5}&audioType={6}", 
                    ApiUrl, _voiceId, System.Net.WebUtility.UrlEncode(text), _speed, _volume, _volumeGain, _audioType);

                LoggerHelper.Log("MsmkLogger", "TTS API URL: " + apiUrl, LogEnum.SysLog);
                LoggerHelper.Log("MsmkLogger", "当前音色ID: " + _voiceId + ", 语速: " + _speed + ", 音量: " + _volume + ", 音量增益: " + _volumeGain, LogEnum.SysLog);

                // 异步下载和播放音频
                Task.Run(() => 
                {
                    try
                    {
                        // 尝试下载音频文件
                        bool downloadSuccess = false;
                        try
                        {
                            using (WebClient client = new WebClient())
                            {
                                // 设置超时时间
                                client.Timeout = 5000; // 5秒超时
                                // 添加调试信息
                                LoggerHelper.Log("MsmkLogger", "开始下载TTS音频文件...", LogEnum.SysLog);
                                client.DownloadFile(apiUrl, tempFilePath);
                                downloadSuccess = true;
                                LoggerHelper.Log("MsmkLogger", "TTS音频文件下载完成", LogEnum.SysLog);
                            }
                        }
                        catch (Exception downloadEx)
                        {
                            LoggerHelper.Log("MsmkLogger", "TTS API下载失败: " + downloadEx.ToString(), LogEnum.SysLog);
                            downloadSuccess = false;
                        }

                        // 检查文件是否存在且大小大于0
                        if (downloadSuccess && File.Exists(tempFilePath) && new FileInfo(tempFilePath).Length > 0)
                        {
                            LoggerHelper.Log("MsmkLogger", "TTS音频文件下载成功: " + tempFilePath + ", 大小: " + new FileInfo(tempFilePath).Length + "字节", LogEnum.SysLog);
                            
                            try
                            {
                                // 播放音频
                                using (SoundPlayer player = new SoundPlayer(tempFilePath))
                                {
                                    player.Play();
                                    LoggerHelper.Log("MsmkLogger", "TTS音频播放成功", LogEnum.SysLog);
                                }
                            }
                            catch (Exception playEx)
                            {
                                LoggerHelper.Log("MsmkLogger", "TTS音频播放失败: " + playEx.Message, LogEnum.SysLog);
                            }
                        }
                        else
                        {
                            LoggerHelper.Log("MsmkLogger", "TTS音频文件下载失败或文件为空，尝试使用本地音频文件", LogEnum.SysLog);
                            
                            // 如果在线API调用失败，尝试使用本地音频文件
                            string localFileName = "支付成功.wav";
                            
                            if (text.Contains("微信"))
                                localFileName = "微信支付成功.wav";
                            else if (text.Contains("支付宝"))
                                localFileName = "支付宝支付成功.wav";
                            else if (text.Contains("银行卡"))
                                localFileName = "支付成功.wav";
                            else if (text.Contains("现金"))
                                localFileName = "支付成功.wav";
                            else if (text.Contains("会员"))
                                localFileName = "会员支付成功.wav";
                            
                            PlayLocalAudioFile(localFileName);
                        }
                    }
                    catch (Exception ex)
                    {
                        LoggerHelper.Log("MsmkLogger", "TTS API异步播放失败: " + ex.Message, LogEnum.SysLog);
                    }
                });
                
                // 立即返回true，不等待音频播放完成
                return true;
            }
            catch (Exception ex)
            {
                LoggerHelper.Log("MsmkLogger", "TTS API播放失败: " + ex.Message, LogEnum.SysLog);
                return false;
            }
        }

        /// <summary>
        /// 播放本地音频文件
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <returns>是否成功播放</returns>
        public bool PlayLocalAudioFile(string fileName)
        {
            try
            {
                // 首先检查指定的文件是否存在
                string filePath = Path.Combine(_localAudioDir, fileName);
                LoggerHelper.Log("MsmkLogger", "尝试播放本地音频文件: " + filePath, LogEnum.SysLog);
                
                if (File.Exists(filePath) && new FileInfo(filePath).Length > 0)
                {
                    LoggerHelper.Log("MsmkLogger", "找到本地音频文件: " + filePath + ", 大小: " + new FileInfo(filePath).Length + "字节", LogEnum.SysLog);
                    
                    try
                    {
                        // 使用SoundPlayer播放 - 异步播放，不阻塞UI线程
                        using (SoundPlayer player = new SoundPlayer(filePath))
                        {
                            player.Play(); // 使用Play而不是PlaySync，确保不阻塞UI线程
                            LoggerHelper.Log("MsmkLogger", "本地音频文件播放成功", LogEnum.SysLog);
                            return true;
                        }
                    }
                    catch (Exception playEx)
                    {
                        LoggerHelper.Log("MsmkLogger", "本地音频文件SoundPlayer播放失败: " + playEx.Message + "，尝试使用SystemSounds", LogEnum.SysLog);
                        
                        try
                        {
                            // 如果SoundPlayer失败，尝试使用System.Media.SystemSounds
                            if (fileName.Contains("成功"))
                            {
                                System.Media.SystemSounds.Asterisk.Play();
                                LoggerHelper.Log("MsmkLogger", "使用SystemSounds.Asterisk播放成功提示音", LogEnum.SysLog);
                                return true;
                            }
                            else if (fileName.Contains("失败"))
                            {
                                System.Media.SystemSounds.Hand.Play();
                                LoggerHelper.Log("MsmkLogger", "使用SystemSounds.Hand播放失败提示音", LogEnum.SysLog);
                                return true;
                            }
                            else
                            {
                                System.Media.SystemSounds.Beep.Play();
                                LoggerHelper.Log("MsmkLogger", "使用SystemSounds.Beep播放通用提示音", LogEnum.SysLog);
                                return true;
                            }
                        }
                        catch (Exception sysEx)
                        {
                            LoggerHelper.Log("MsmkLogger", "SystemSounds播放也失败: " + sysEx.Message, LogEnum.SysLog);
                            return false;
                        }
                    }
                }
                else
                {
                    // 如果指定的文件不存在或为空，尝试查找通用的支付成功音频文件
                    LoggerHelper.Log("MsmkLogger", "本地音频文件不存在或为空: " + filePath, LogEnum.SysLog);
                    
                    string genericFile = Path.Combine(_localAudioDir, "支付成功.wav");
                    if (File.Exists(genericFile) && new FileInfo(genericFile).Length > 0)
                    {
                        LoggerHelper.Log("MsmkLogger", "尝试播放通用支付成功音频文件: " + genericFile, LogEnum.SysLog);
                        
                        try
                        {
                            using (SoundPlayer player = new SoundPlayer(genericFile))
                            {
                                player.Play(); // 使用Play而不是PlaySync，异步播放
                                LoggerHelper.Log("MsmkLogger", "通用支付成功音频文件播放成功", LogEnum.SysLog);
                                return true;
                            }
                        }
                        catch (Exception playEx)
                        {
                            LoggerHelper.Log("MsmkLogger", "通用支付成功音频文件播放失败: " + playEx.Message + "，尝试使用SystemSounds", LogEnum.SysLog);
                            
                            try
                            {
                                System.Media.SystemSounds.Asterisk.Play();
                                LoggerHelper.Log("MsmkLogger", "使用SystemSounds.Asterisk播放成功提示音", LogEnum.SysLog);
                                return true;
                            }
                            catch (Exception sysEx)
                            {
                                LoggerHelper.Log("MsmkLogger", "SystemSounds播放也失败: " + sysEx.Message, LogEnum.SysLog);
                                return false;
                            }
                        }
                    }
                    else
                    {
                        LoggerHelper.Log("MsmkLogger", "通用支付成功音频文件也不存在或为空，尝试使用SystemSounds", LogEnum.SysLog);
                        
                        try
                        {
                            if (fileName.Contains("成功"))
                            {
                                System.Media.SystemSounds.Asterisk.Play();
                                LoggerHelper.Log("MsmkLogger", "使用SystemSounds.Asterisk播放成功提示音", LogEnum.SysLog);
                            }
                            else if (fileName.Contains("失败"))
                            {
                                System.Media.SystemSounds.Hand.Play();
                                LoggerHelper.Log("MsmkLogger", "使用SystemSounds.Hand播放失败提示音", LogEnum.SysLog);
                            }
                            else
                            {
                                System.Media.SystemSounds.Beep.Play();
                                LoggerHelper.Log("MsmkLogger", "使用SystemSounds.Beep播放通用提示音", LogEnum.SysLog);
                            }
                            return true;
                        }
                        catch (Exception sysEx)
                        {
                            LoggerHelper.Log("MsmkLogger", "SystemSounds播放失败: " + sysEx.Message, LogEnum.SysLog);
                            return false;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.Log("MsmkLogger", "播放本地音频文件失败: " + ex.Message, LogEnum.SysLog);
                return false;
            }
        }

        /// <summary>
        /// 播放结算语音提示
        /// </summary>
        /// <param name="amount">结算金额</param>
        public void PlayCheckoutAmount(decimal amount)
        {
            try
            {
                LoggerHelper.Log("MsmkLogger", "开始播报结算金额: " + amount.ToString("0.00") + ", TTS类型: " + _ttsType, LogEnum.SysLog);
                
                // 确保TLS 1.2
                System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)3072;
                
                string message = string.Format("共计{0}元，请选择支付方式", amount.ToString("0.00"));
                
                if (_ttsType == "local")
                {
                    // 本地模式下，只播放固定提示音，不播报具体金额
                    string fixedFileName = "结算提示.wav";
                    LoggerHelper.Log("MsmkLogger", "使用本地音频播报固定结算提示，文件: " + fixedFileName, LogEnum.SysLog);
                    bool fixedSuccess = PlayLocalAudioFile(fixedFileName);
                    LoggerHelper.Log("MsmkLogger", "本地音频播报固定结算提示" + (fixedSuccess ? "成功" : "失败"), LogEnum.SysLog);
                }
                else
                {
                    // 在线模式下，使用API播报具体金额
                    LoggerHelper.Log("MsmkLogger", "使用在线TTS播报结算金额，消息: " + message, LogEnum.SysLog);
                    
                    // 直接使用PlayTtsApi方法播放
                    bool success = PlayTtsApi(message);
                    LoggerHelper.Log("MsmkLogger", "在线TTS播报结算金额" + (success ? "成功" : "失败"), LogEnum.SysLog);
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.Log("MsmkLogger", "播报结算金额异常: " + ex.ToString(), LogEnum.ExceptionLog);
            }
        }

        /// <summary>
        /// 播放欢迎消息
        /// </summary>
        /// <param name="payType">支付类型，如"微信"、"支付宝"</param>
        public void PlayWelcome(string payType)
        {
            if (_ttsType == "local")
            {
                // 使用本地音频文件
                string fileName = "欢迎光临，请出示" + payType + "付款码.wav";
                PlayLocalAudioFile(fileName);
            }
            else
            {
                // 使用API
                string message = string.Format("欢迎光临，请出示{0}付款码", payType);
                PlayTtsApi(message);
            }
        }

        /// <summary>
        /// 播放支付方式选择语音提示
        /// </summary>
        /// <param name="payType">支付类型，如"微信"、"支付宝"</param>
        /// <param name="amount">支付金额</param>
        public void PlayPaymentMethod(string payType, decimal amount)
        {
            if (_ttsType == "local")
            {
                // 使用本地音频文件
                string fileName = "请出示" + payType + "付款码.wav";
                PlayLocalAudioFile(fileName);
            }
            else
            {
                // 使用API
                string message = string.Format("请出示{0}付款码，支付{1}元", payType, amount.ToString("0.00"));
                PlayTtsApi(message);
            }
        }

        /// <summary>
        /// 播放支付成功消息（含金额）
        /// </summary>
        /// <param name="payType">支付类型，如"微信"、"支付宝"</param>
        /// <param name="amount">支付金额</param>
        public void PlayPaymentSuccess(string payType, decimal amount)
        {
            if (_ttsType == "local")
            {
                // 使用本地音频文件
                string fileName = payType + "支付成功.wav";
                PlayLocalAudioFile(fileName);
            }
            else
            {
                // 使用API
                string message = string.Format("{0}支付成功，收款{1}元，谢谢惠顾", payType, amount.ToString("0.00"));
                PlayTtsApi(message);
            }
        }

        /// <summary>
        /// 播放支付失败消息
        /// </summary>
        /// <param name="payType">支付类型，如"微信"、"支付宝"</param>
        public void PlayPaymentFailed(string payType)
        {
            if (_ttsType == "local")
            {
                // 使用本地音频文件
                string fileName = payType + "支付失败.wav";
                PlayLocalAudioFile(fileName);
            }
            else
            {
                // 使用API
                string message = string.Format("{0}支付失败，请重试", payType);
                PlayTtsApi(message);
            }
        }

        /// <summary>
        /// 播放会员支付成功消息
        /// </summary>
        /// <param name="memberName">会员名称</param>
        /// <param name="amount">支付金额</param>
        public void PlayMemberPaymentSuccess(string memberName, decimal amount)
        {
            if (_ttsType == "local")
            {
                // 使用本地音频文件
                string fileName = "会员支付成功.wav";
                PlayLocalAudioFile(fileName);
            }
            else
            {
                // 使用API
                string message = string.Format("尊敬的会员{0}，您已成功支付{1}元，谢谢惠顾", memberName, amount.ToString("0.00"));
                PlayTtsApi(message);
            }
        }

        /// <summary>
        /// 播放测试语音
        /// </summary>
        /// <param name="text">测试文本</param>
        /// <returns>是否成功播放</returns>
        public bool PlayTestVoice(string text)
        {
            if (_ttsType == "local")
            {
                return PlayLocalAudioFile("测试语音.wav");
            }
            else
            {
                return PlayTtsApi(text);
            }
        }
    }

    // WebClient扩展类，添加超时属性
    public class WebClient : System.Net.WebClient
    {
        private int _timeout = 30000; // 默认30秒
        
        public int Timeout 
        { 
            get { return _timeout; } 
            set { _timeout = value; }
        }

        protected override WebRequest GetWebRequest(Uri uri)
        {
            WebRequest request = base.GetWebRequest(uri);
            if (request != null)
            {
                request.Timeout = Timeout;
            }
            return request;
        }
    }
}